Distributed Tracing: the journey, not the event

A revision session built only on what makes distributed tracing fundamentally different from distributed logging — plus a real deployment section and a leadership decision-making section. Click a question to think first — reveal only when you're ready to check yourself.

12 segments ~3 hrs, self-paced Format: think → answer aloud → reveal Goal: reasoning, not recall
offset 00

The mental model shift

Logging asks: "what happened in each service?" Tracing asks: "how did one request travel across many services, in what order, for how long, and where exactly was time spent?" Everything below falls out of that one difference.

Logging model:  many log events, searched by service / level / time / trace_id
Tracing model:  one request -> broken into spans -> spans form a tree/DAG -> full path visible

Logs are event records.
Traces are causality and timing graphs.
Q1You already have correlated logs (same trace_id stamped everywhere). Why isn't that "distributed tracing"?reveal
Correlated logs tell you which events belong to the same request, but not the parent-child structure between them — who called whom, what ran inside what, and how long each nested step took. That structure is the actual product of tracing.
Q2What is the real primary object in tracing — is it a log line?reveal
No. The primary object is a Trace, composed of Spans. A log line is a point-in-time fact; a span is a timed unit of work with a start, an end, and a place in a causal tree.
Q3What new question does tracing answer that logging structurally cannot answer well?reveal
"Where exactly did the latency happen?" Logs can tell you a step took 500ms if someone logged it, but only a span tree can show you that step's 500ms against the total request time and against its siblings.
Q4If someone says "we already have distributed traceability" but really means "we have a shared correlation ID," what's missing?reveal
Everything that makes tracing tracing: span hierarchy, durations, parallelism visibility, and a reconstructable execution path. A shared ID is necessary but nowhere near sufficient.
offset 01

Trace & span fundamentals

The primary object isn't "a correlated log line" — it's Trace → Spans → parent-child tree/DAG. A trace is the whole request journey; a span is one timed unit of work inside that journey.

Trace T100
 +--> Span S1 : Gateway request
       +--> Span S2 : Auth call
       +--> Span S3 : Order call
               +--> Span S4 : Inventory call
               +--> Span S5 : Payment call
Q5What should a span represent — one HTTP request, one DB call, one internal method?reveal
Generally a meaningful unit of work at a boundary — a network hop, a DB/cache call, a queue publish/consume, or a significant business step. Not every internal method call deserves its own span.
Q6If span granularity is too coarse, what is lost?reveal
You lose the ability to localize latency — you'll know "Order Service took 700ms" but not whether that was a slow DB call, a slow downstream dependency, or CPU-bound business logic.
Q7If span granularity is too fine, what happens?reveal
Too much overhead, too much data, too much noise — traces become unreadable trees with hundreds of spans, storage/ingestion cost balloons, and the signal (where's the real latency) drowns in detail.
Q8What's the actual difference between a span and a well-formatted log line with a duration field?reveal
A log line is self-contained — nothing forces it to know its place in a larger structure. A span carries trace_id, span_id, and parent_id by construction, so it composes into a tree automatically. The log line only composes into a tree if a human reconstructs it later.
offset 02

Parent-child causality — the real heart

Logging correlation stops at "these events share a trace_id." Tracing goes deeper — it needs parent span id, child span id, causal structure, not just a common label scattered across services.

Gateway Span S1
   +--> Auth Span S2
   +--> Order Span S3
          +--> Payment Span S4
          +--> Inventory Span S5

This is much stronger than: "all logs share trace_id=T100"
Because now we know who called whom, in what nesting, for how long.
Q9Why is trace_id alone insufficient without span hierarchy?reveal
Because trace_id only groups events into a bucket. It doesn't tell you the nesting — which call triggered which, and in what order. Traceability is about the causal path, not just common correlation.
Q10If a service emits spans without correct parent linkage, what happens?reveal
The trace becomes broken or misleading — spans either float as orphans, attach to the wrong parent, or the tool silently guesses a structure that isn't real. Debugging on a wrong tree is worse than no tree.
Q11Two spans share the same trace_id but have no parent_id set at all. What can you still conclude — and what can't you?reveal
You can conclude they belong to the same request. You cannot conclude who called whom, whether they ran sequentially or in parallel, or which one's failure caused the other's. That's the exact gap between logging correlation and tracing.
Q12Should every downstream service just forward the trace_id it received, or create a new span correctly?reveal
Create a new child span, with its own span_id and the incoming span_id set as its parent_id. Forwarding trace_id alone without creating a proper child span destroys the causal tree even though the trace still "looks" connected.
offset 03

Timing as first-class — critical path

Logging usually stores timestamps as metadata. Tracing makes duration the central organizing fact — a span tree with timings is a latency-decomposition tool, not just a record of when things happened.

Trace T100 — total 900ms
Gateway Span        [-------------------- 900 ms --------------------]
Auth Span           [--- 40 ms ---]
Order Span          [---------------- 700 ms ----------------]
Inventory Span      [-- 80 ms --]
Payment Span        [----------- 500 ms -----------]
Q13What is the "critical path" of a trace?reveal
The chain of spans that actually determined total request duration — the sequence where, if any one span got faster, the overall request would get faster too. Spans that ran in parallel with slack time are not on the critical path even if they took a while.
Q14Why can the sum of all span durations exceed the total trace duration?reveal
Because of overlap / parallelism — if three spans run concurrently for 200ms each, they sum to 600ms of "work" but only cost 200ms of wall-clock time. Summing span durations without accounting for concurrency overstates the real cost.
Q15Why does tracing answer "where did the time go" better than logs with timestamps?reveal
Logs can tell you "Payment took 500ms" in isolation. Tracing tells you "that 500ms dominated the total 900ms request and sat on the critical path" — the same fact, but placed inside the structure that makes it actionable.
Q16A trace shows Payment span = 500ms inside a 1200ms total, but Payment ran in parallel with two other 400ms spans. Is Payment automatically your bottleneck?reveal
Not automatically — you need to check if Payment is on the critical path. If the other branches finish well before Payment and the parent waits on all of them, Payment is the bottleneck. If some sequential step outside the parallel block dominates instead, optimizing Payment won't move the needle.
offset 04

Context propagation across service & async boundaries

Correlation IDs were "useful" in logging. In tracing, propagation must carry trace_id, span_id, parent context, and sampling flags precisely — and it gets genuinely hard the moment a queue or topic sits between two services.

Client
  -> Gateway creates Trace T100, Span S1
       | propagate context
       v
     Order Service creates child Span S2
       | propagate context
       v
     Payment Service creates child Span S3

Async case:
API Span -> publish message -> Queue/Topic -> Worker Span
(is the worker span a child of the API span, or linked more loosely?)
Q17What exactly needs to be propagated between services — is trace_id enough?reveal
No. You need trace_id, the current span_id (to become the parent), the sampling decision/flag, and optionally trace state. Propagating trace_id alone loses the parent-child chain the moment it crosses a boundary.
Q18If processing happens minutes later via a queue, is a single end-to-end trace still the right model?reveal
Often no — a single unbroken trace implies a live, bounded request. For long-delayed async work, many systems deliberately model it as a linked trace (a reference, not a parent-child span) so dashboards don't show a "hanging" 10-minute span that misrepresents what actually happened.
Q19A message is published to a topic and consumed by a worker later. What breaks if you don't explicitly design for this boundary?reveal
The trace silently ends at publish — the worker either starts a brand-new, disconnected trace, or (worse) inherits stale context that misattributes its work to the wrong request. Either way, you lose the ability to answer "what happened to this event after it was published."
Q20Should business metadata (tenant_id, experiment_id, region) travel as tracing "baggage," or stay in logs and span tags?reveal
Sparingly, as baggage, only if every downstream service genuinely needs it for its own decisions (e.g. routing by tenant). Baggage propagates on every hop and adds overhead — most metadata belongs on the span itself as a tag, visible for that span only, not forced onto the whole trace.
offset 05

Concurrency & fan-out

Logs are read largely linearly. Traces show parallel branches natively — this is one of tracing's sharpest advantages over logging for fan-out call patterns.

Gateway Span
   +--> Auth Span
   +--> in parallel:
         +--> Inventory Span
         +--> Pricing Span
         +--> Recommendation Span

Timeline view:
Gateway        [--------------------------------------]
Inventory         [------]
Pricing           [----------]
Recommendation    [-------------------]
Q21Three downstream calls fire concurrently from one service. Can scattered logs alone easily show that they ran in parallel, not sequence?reveal
Usually not clearly — logs interleave by wall-clock write time across threads/services, and a reader has to mentally reconstruct overlap. A span tree with start/end timestamps shows the overlap directly in a waterfall view.
Q22Of three parallel branches, one is slow and two are fine. How does tracing surface that versus logging?reveal
In a waterfall view, the slow branch's span is visually longer and clearly extends past its siblings — instantly identifiable. In logs, you'd need to manually diff timestamps across three separate log streams to notice the same thing.
Q23Why is fan-out concurrency a natural fit for the span-tree model specifically (not just "more spans")?reveal
Because sibling spans under the same parent, with their own start/end times, encode "ran independently, same trigger" for free — no extra field needed. The tree structure itself expresses concurrency; you don't have to infer it.
Q24If a parent span waits on 3 children, and one takes far longer than the other two combined, is optimizing the fast two worth doing?reveal
Almost never — the parent's total time is bounded by the slowest child when they run in parallel. Optimizing the fast two buys nothing unless the slow one is also fixed; this is exactly the kind of wasted-effort trap a span tree prevents.
offset 06

Error semantics inside request structure

Logging stores many scattered error events. Tracing marks failure in the context of the request path — which is a structurally stronger story than isolated error logs.

Trace T100
Gateway Span      OK
Order Span        OK
Payment Span      ERROR timeout
Inventory Span    not called / cancelled
Q25Why is one error span often more powerful than many scattered error logs describing the same failure?reveal
Because the error span sits inside the request structure and latency path — you immediately see what led up to it, what ran alongside it, and what happened downstream, instead of piecing that together from timestamps across five separate log files.
Q26Should a span carry a structured status (OK / ERROR / TIMEOUT / CANCELLED), or is a free-text error log attached to it enough?reveal
Structured status is essential — it's what lets tracing backends filter and alert on "show me all traces with an ERROR span" at query time. A free-text log requires full-text search and doesn't compose into dashboards or SLOs the same way.
Q27Can tracing show whether sibling calls continued or were aborted after one branch failed?reveal
Yes — this is a tracing-specific strength. If Inventory's span never starts, or starts and is marked CANCELLED, the tree itself documents the fan-out's failure-handling behavior, something isolated error logs rarely capture explicitly.
Q28A parent span is marked OK even though a child span errored. What does that usually mean, and is it a bug?reveal
It usually means the parent caught and handled the child's failure (a retry succeeded, a fallback was used, the error was non-critical). It's not automatically a bug — but it's a signal worth checking, since a parent silently swallowing every child error can hide real degradation.
offset 07

Sampling — why it's far more central than in logging

Logging can often afford to retain most events. A full span tree for every request, at scale, becomes very expensive very fast — so tracing leans on sampling far more heavily.

100,000 requests/sec
If every request creates 20 spans -> 2,000,000 spans/sec

Strategies:
sample 1% of everything
sample all errors
sample slow traces
sample priority traffic (tail sampling)
Q29Why is sampling much more central in tracing than in log sampling?reveal
Because a single request can generate dozens of spans across many services almost instantly — the volume multiplier is far steeper than one log line per event, so unsampled tracing at scale is often prohibitively expensive to ingest and store.
Q30Should sampling decide at the head (start of request) or the tail (after seeing the outcome)?reveal
Both have a place. Head sampling is cheap and simple but blind — it might drop the one trace that turns out to matter. Tail sampling waits to see the outcome before deciding, so it can deliberately keep error traces and slow traces — at the cost of buffering and more complex infrastructure.
Q31Why is tail sampling attractive despite being harder to build?reveal
Because it can preserve exactly the traces you'd otherwise regret losing — error traces, slow traces, and traces on interesting/priority paths — instead of randomly keeping 1% and hoping the important ones survive.
Q32If you sample one span but lose its parent or children in the process, is the trace still useful?reveal
Rarely — tracing's value depends on whole-trace coherence. A sampling decision must be made per-trace (usually at the root), not per-span, or you end up with orphaned fragments that can't be reassembled into a meaningful path.
offset 08

Tracing vs logs vs metrics — the real boundary

The most senior answer isn't "tracing replaces logging" — it's knowing exactly which question each tool is built to answer, and wiring them together rather than duplicating effort.

Reach for logs whenReach for tracing when
You need the detailed local story of one service at one momentYou need the cross-service journey of one request
Full-text search over arbitrary event detail is the workflowLatency decomposition / critical-path analysis is the workflow
Debugging inside a single component's internal stateDebugging "why is checkout slow" across many components
You want every event, cheaply, with flexible queryingYou want a small number of complete, coherent request paths
Q33Should tracing replace logging?reveal
No. Logs answer detailed local events; traces answer the cross-service journey and latency. Together, from a span you jump to related logs, and from logs you jump to the trace_id — neither one alone tells the full story.
Q34Should every log line carry trace_id and span_id context?reveal
Yes — this is a very strong practice. It's what lets you pivot from "I found a slow span in the trace waterfall" to "now show me the exact logs for that span" in one click, instead of manually correlating timestamps across systems.
Q35If someone asks "why is checkout slow," is the better first stop logs or the trace waterfall?reveal
Usually the trace waterfall — it immediately shows which service/span dominates total time. Logs are the right next step once you know where to look, to understand why that specific step was slow.
offset 09

Our deployment — Wealth / Demat Platform tracing footprint

This is the shape of the tracing footprint behind mutual fund order flow, IPO allotment, NSDL demat sync, PolicyBazaar insurance journeys, and loans — the numbers to have ready when asked "have you actually run this in production?"

Instrumented services
~35 of 80+
Backend
OTel + collector
Base sampling
5% head sample
Tail-sampled
100% errors + p95+
Avg span depth
6–9 per request
Trace retention
24h hot storage
FlowServices in pathTypical spansKnown hotspot
MF redemption requestgateway → order-svc → NAV-svc → payment → ledger → notification~12NAV cutoff window latency
IPO allotment syncmofsl-webhook-adapter → allotment-svc → notification-dispatcher~6MOFSL callback jitter
Demat instant account openonboarding-svc → nsdl-adapter → kyc-svc → demat-svc~10NSDL external call variance
Insurance journeypolicy-gateway → policybazaar-adapter → policy-sync-svc~7Third-party API span missing internal retries
Loan against MF (LAMF)loan-svc → valuation-svc → lien-marking-svc → disbursal-svc~9Lien-marking async boundary

Roughly 35 of 80+ microservices currently emit spans. The biggest coverage gap sits at the NSDL/MOFSL/PolicyBazaar external boundaries, where outbound calls are traced but internal retry/backoff logic inside those adapters often isn't.

Real issues we've actually hit

Broken trace at the async boundary
A redemption event published to a queue and picked up by a worker service 40s later showed up as two disconnected traces. Fix: explicit trace-link (not parent-child) injected into message headers at publish time, resolved at consume time.
Over-instrumentation in the NSDL adapter
A team added a span to every internal method call, producing 80+ spans per request and overwhelming the trace UI. Fix: pruned to boundary-only spans (network, DB, external call).
The complaint trace got sampled out
A specific customer's failed redemption fell outside the 5% head sample — no trace existed to investigate. Fix: moved error paths to guaranteed tail-sampling regardless of head-sample decision.
Retry logic invisible inside a single span
The PolicyBazaar adapter retried a timing-out call 3 times internally, but it appeared as one long span with no visibility into the retries. Fix: each retry attempt now gets its own child span with an attempt-number tag.
Clock skew across containers
Two services on nodes with ~150ms clock drift produced spans that appeared to start before their parent. Fix: NTP sync enforced cluster-wide; tracing backend also clamps visually implausible offsets.

The line worth saying in an interview: "We treat span boundaries and sampling policy as design-time decisions, not runtime accidents — most of our trace-quality incidents came from someone instrumenting too much or too little, not from the tracing backend misbehaving."

offset 10

Rapid fire — say the "why" out loud, then move on

No hidden answers here — if you can answer each in one breath, you're ready. If you stall on one, that's your revision signal.

  1. Why is trace_id alone not enough without span hierarchy?
  2. Why is tracing about causality and timing, not just event collection?
  3. Why does tracing answer latency decomposition better than logs?
  4. Why is parent-child span structure the real heart of traceability?
  5. Why is sampling much more central in tracing than in logging?
  6. How should async boundaries be represented in traces — parent-child, or linked traces?
  7. What should count as a span, and what is too fine-grained?
  8. Why does tracing naturally reveal service dependency graphs that nobody documented?
  9. Why is full-trace retrieval a different storage/query problem than log search?
  10. Why should logs and traces be linked, not merged into one thing?
offset 11

Leadership perspectives — same incident, four minds

Seven situations. Each one is read differently by a developer, an architect, a CTO, and a director. Click to reveal how the same incident produces four different decisions — and the one "invisible question" that separates leading the system from just fixing it.

L1A mutual fund redemption trace shows a 3.2s end-to-end request. The Payment span alone is 2.6s, but nobody had noticed until a customer complained.reveal
Digging in, Payment's 2.6s wasn't one slow call — it was three sequential retries against a flaky downstream bank API, each waiting the full timeout before failing over. The trace existed the whole time; nobody had a dashboard watching for "any span over X ms" in production.
Developer

Tunes the retry timeout down — helpful locally, doesn't address why nobody saw this before a customer did.

Architect

Weighs alerting on span-duration thresholds (proactive, needs tuning to avoid noise) against relying on customer complaints (reactive, cheap, always too late).

CTO

Notes tracing was deployed as a debugging tool, not an observability product — nobody owns turning trace data into alerts, dashboards, or SLOs.

Director

Asks the harder question: how many other slow spans exist right now, silently, because tracing data is collected but never watched?

The invisible leadership question: Do we have a single dashboard that would have caught this without a customer telling us? If not, we're generating trace data, not observability.
Learning: Collecting traces isn't the same as watching them. A trace sitting in storage that nobody's threshold ever fires on is functionally the same as no trace at all — until, as here, it's needed retroactively.
L2A redemption order publishes an event to Kafka; a settlement worker consumes it 40 seconds later. The trace ends at publish — nobody can see what happened after.reveal
A settlement bug caused silent duplicate processing for a handful of orders. Without a connected trace across the queue boundary, tracking down which service actually caused the duplication took two days of manually correlating logs by order_id across five services.
Developer

Adds order_id to every log line in the worker — helps this time, doesn't fix the structural gap for the next async flow.

Architect

Decides between linking the worker's trace to the publisher's trace (context-aware, more setup) versus accepting that async work will always need log correlation instead of tracing.

CTO

Points out this is now the third incident where an async boundary caused a multi-day investigation — the fix (context propagation via message headers) is a platform investment, not a per-team task.

Director

Frames it as a build-vs-tolerate decision: invest in a shared messaging-context library once, or keep paying two engineer-days per incident indefinitely.

The invisible leadership question: How many of our async flows have this same blind spot right now, waiting for their own two-day investigation?
Learning: Tracing that stops at a queue isn't broken tracing — it's untraced. Async boundaries need deliberate design (trace-link injection into message headers), not an assumption that "the trace_id will just carry over."
L3A team instruments every method call inside the NSDL adapter. Traces balloon to 80+ spans per request, and the trace UI becomes unusable.reveal
The team's intent was good — "more visibility can't hurt." Six weeks later, ingestion costs for that one service exceeded the rest of the platform combined, and engineers started ignoring the NSDL traces entirely because they took too long to read.
Developer

Manually collapses spans in the UI when reading a trace — a workaround, not a fix, and it doesn't reduce ingestion cost.

Architect

Defines instrumentation boundaries explicitly — network calls, DB/cache calls, external dependencies, key business steps — and removes spans for pure in-process logic.

CTO

Realizes there was no instrumentation guideline at all — every team decided span granularity independently, with wildly different philosophies.

Director

Sees the actual cost: engineers now distrust tracing data because reading it takes longer than reading logs — the tool built to save time started costing more of it.

The invisible leadership question: Do we have a written instrumentation standard that every team can be pointed to, or is span granularity purely a matter of individual taste?
Learning: More spans is not more observability past a certain point — it's noise with a bill attached. The instinct to "trace everything" needs an explicit boundary discipline, or tracing degrades into a more expensive, harder-to-read version of logging.
L4A high-value customer's redemption fails. Support escalates. Engineering goes to find the trace — it was never sampled; the 5% head-sample rate simply skipped it.reveal
Reconstructing what happened takes hours of manual log correlation across six services, because the one artifact designed specifically to make this fast — the trace — doesn't exist for this request.
Developer

Raises the head-sample rate from 5% to 20% — reduces the odds of this happening again, but doesn't guarantee it and multiplies cost fourfold.

Architect

Redesigns sampling as tail-based: sample everything provisionally, then decide retention after seeing the outcome — guaranteeing errors and slow requests are always kept regardless of a random head-sample coin flip.

CTO

Weighs the infrastructure cost of tail sampling (buffering, delayed decision) against the recurring cost of untraceable high-value incidents.

Director

Asks a sharper question: should sampling policy differ by customer tier or transaction value at all, or is uniform random sampling itself the wrong default for a financial platform?

The invisible leadership question: Is our sampling strategy actually aligned with which requests matter most to the business, or is it just "whatever's cheapest to run"?
Learning: Random head sampling treats every request as equally disposable. In a financial system, errors, slow requests, and high-value transactions are exactly the ones you can't afford to lose — which is precisely what naive uniform sampling is most likely to drop.
L5The PolicyBazaar integration times out intermittently. The trace shows one long external-call span — but internally, the adapter was silently retrying three times before failing.reveal
Without visibility into the retries, the team initially assumed PolicyBazaar's API itself was consistently slow. In reality, the first two attempts failed fast and only the third succeeded slowly — a completely different problem (retry/backoff tuning) than what the single span suggested (a genuinely slow upstream).
Developer

Adds a child span per retry attempt with attempt-number and outcome tags — makes the real behavior visible immediately.

Architect

Generalizes the fix: any retry logic anywhere in the platform should default to child-span-per-attempt as a standard instrumentation pattern, not a one-off fix for this adapter.

CTO

Points out the team spent two weeks chasing "PolicyBazaar is slow" as a vendor problem when it was actually an internal retry configuration issue — a costly misdiagnosis caused entirely by under-instrumentation.

Director

Names the pattern: every external-vendor integration in the platform should be assumed to have hidden retry logic until proven otherwise, and audited accordingly.

The invisible leadership question: How many other "the vendor is slow" tickets in our backlog are actually "our retry logic is invisible" problems in disguise?
Learning: A single span that wraps hidden internal complexity (retries, fallbacks, circuit breakers) doesn't just lose detail — it can point blame at the wrong system entirely. If work happens inside a call, that work deserves its own spans.
L6A trace waterfall shows a child span apparently starting before its parent span. The on-call engineer assumes the tracing tool is broken and moves on.reveal
It wasn't a tool bug — two containers had ~150ms of clock drift between them. The "impossible" ordering was real data, correctly reported, describing an environment problem nobody had checked in months.
Developer

Ignores the anomaly as a rendering glitch — loses a real signal about infrastructure health.

Architect

Treats implausible span ordering as a first-class alert condition — it usually means clock skew, not a broken tool, and clock skew corrupts every latency number on that host, not just this one trace.

CTO

Realizes NTP sync monitoring was never set up cluster-wide — a basic infra hygiene gap that had been silently corrupting trace accuracy for an unknown period.

Director

Asks how much of the platform's "the tracing tool is unreliable" reputation was actually caused by unmonitored clock drift, and whether that reputation is now discouraging engineers from trusting good data.

The invisible leadership question: When trace data looks wrong, do we default to "the tool is broken" or "the tool is telling us something true that we don't want to hear"?
Learning: Distributed tracing is only as trustworthy as the clocks underneath it. An engineer's instinct to dismiss "impossible" timing data is usually wrong — it's far more often a real infrastructure fact (clock skew, NTP failure) than a rendering bug.
L7A regulator asks for the exact call sequence and timing of a specific IPO allotment failure from 5 days ago. Trace retention is 24 hours — the data is already gone.reveal
The team scrambles to reconstruct the incident from logs, but logs alone can't establish the precise cross-service causal sequence the regulator wants proven — the exact thing tracing was built to provide, and the exact thing that had already expired.
Developer

Extends retention going forward — fixes the next incident, not this one, and doesn't help the current regulatory request.

Architect

Distinguishes hot trace storage (fast, expensive, short retention, for active debugging) from cold trace archival (cheaper, longer retention, for compliance-grade reconstruction) — the platform only ever built the first.

CTO

Points out this is a governance gap, not a technical one: nobody defined what retention regulated financial flows actually require before building the tracing pipeline.

Director

Names the real question: for flows with regulatory exposure — IPO allotment, redemptions, demat transfers — was retention ever a deliberate compliance decision, or just whatever the default hot-storage window happened to be?

The invisible leadership question — the one that separates leaders: If a regulator asks for proof of exact request sequencing on any of our regulated flows tomorrow, do we know precisely how far back we can actually answer — and did we choose that number deliberately, or did it just default to whatever the tracing vendor's free tier gave us?
Learning: Tracing retention is a business decision wearing an infrastructure costume. 24 hours is fine for "why is checkout slow right now" and completely inadequate for "prove what happened on a regulated transaction five days ago." The gap between those two needs is exactly where compliance-grade cold storage belongs — and it has to be designed in before the regulator asks, not after.

The pattern underneath all seven: developers ask "how do I make this trace/span correct," architects ask "what instrumentation or propagation design caused this and what's the durable fix," CTOs ask "what governance or platform-standard gap let this happen," and directors ask "what's the business or compliance cost, and who owns this decision." A leadership role means holding all four at once — and knowing which one should drive the call, each time.